package com.jotta.client.communicate;

import java.io.File;
import java.util.Iterator;
import java.util.concurrent.LinkedBlockingQueue;

import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;

import com.jotta.client.R;
import com.jotta.client.data.FileInfo;
import com.jotta.client.data.PictureInfo;
import com.jotta.client.dataaccess.DataAccess;
import com.jotta.client.exception.NetworkException;
import com.jotta.client.exception.ServerException;
import com.jotta.client.setting.SettingManager;

public class DownloadPicturesThread extends Thread {

    private LinkedBlockingQueue<PictureInfo> downloadQueue = new LinkedBlockingQueue<PictureInfo>();

    Handler pictureDownloadedHandler;
    Handler stopDownloadThreadUnexpectly;
    private boolean isRunning = false;

    public DownloadPicturesThread(Handler pictureDownloadedHandler, Handler stopDownloadThreadUnexpectly) {
        super();
        this.pictureDownloadedHandler = pictureDownloadedHandler;
        this.stopDownloadThreadUnexpectly = stopDownloadThreadUnexpectly;
    }

    public boolean isExist(PictureInfo pictureInfo) {
        for (PictureInfo item : downloadQueue) {
            if (item.getLocalPathOfItem().equals(pictureInfo.getLocalPathOfItem()))
                return true;
        }
        return false;
    }

    public void addDonwloadItem(PictureInfo pictureInfo) {
        if (!pictureInfo.isDownloaded() && !isExist(pictureInfo)) {
            //Log.i(Configuration.APP_TAG, "Add file to download queue: " + pictureInfo.getTitle());
            downloadQueue.add(pictureInfo);
        }
    }

    private void record2Database(FileInfo fileInfo) {
        DataAccess.getInstance().recordNewFileIntoDatabase(fileInfo);
    }

    public void start() {
        if (!this.isRunning) {
            //Log.i(Configuration.APP_TAG, "Start Thread");
            this.isRunning = true;
            super.start();
        }
    }

    public void stopThread() {
        //Log.i(Configuration.APP_TAG, "Stop Thread");
        this.isRunning = false;
    }

    @Override
    public void run() {

        while (isRunning) {

            //String headTitle = downloadQueue.peek() == null ? "null" : downloadQueue.peek().getTitle();
            //Log.i(Configuration.APP_TAG, "Head item " + headTitle);

            if (downloadQueue.size() > 0) {

                PictureInfo item = downloadQueue.peek();
                if (!item.isDownloaded()) {
                    if (item.getFileSize() > SettingManager.getInstance().getLocalFreeSpace()) {
                        String message = Configuration.getRes().getString(R.string.not_enough_free_space_reason);
                        sendMessage2StopDownloadThreadUnexpectlyHandle(message);
                        downloadQueue.clear();
                        return;

                    } else {
                        //Log.i(Configuration.APP_TAG, "Start download: " + item.getTitle());
                        String message = downloadFileFromSever(item);
                        if (!message.equals(Configuration.GET_DATA_SUCCESSFUL_MESSAGE)) {
                            if (message.equals(
                                    new NetworkException(Configuration.getRes().getString(
                                            R.string.unexpected_stop_downloading)).getErrorMessage())) {
                                return;
                            } else
                                sendMessage2StopDownloadThreadUnexpectlyHandle(message);

                        } else {
                            File file = new File(item.getLocalPathOfItem());
                            long downloadSize = file.length();
                            if (downloadSize != item.getFileSize()) {
                                file.delete();

                            } else {
                                try {
                                    Thread.sleep(100);
                                } catch (InterruptedException e) {
                                    //Log.w(Configuration.APP_TAG, "InterruptedException: " + e.getMessage());
                                    //e.printStackTrace();
                                }

                                record2Database(item);
                                downloadQueue.remove();
                                if (isRunning) {
                                    sendMessage2PictureDownloadedHandler(item.getTitle());
                                }

                            }
                        }
                    }
                }
            } else {
                //Log.i(Configuration.APP_TAG, "download size = 0");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    private synchronized String downloadFileFromSever(FileInfo fileInfo) {
        ServerCommunicator communicator = ServerCommunicator.getInstance();
        Configuration.setStateOfClient(StateOfClient.DOWNLOADING_PICTURE);
        String serverMessage = "";

        try {
            String downloadPath = fileInfo.getDownloadPathOfItem();
            String filePath = fileInfo.getServerPathOfItem();
            long fileSize = fileInfo.getFileSize();
            communicator.downloadFile(downloadPath, filePath, fileSize);
            serverMessage = Configuration.GET_DATA_SUCCESSFUL_MESSAGE;

        } catch (ServerException e) {
            serverMessage = e.getErrorMessage();
        } catch (NetworkException e) {
            serverMessage = e.getErrorMessage();
        } catch (Exception e) {
            if (e.getMessage() != null) {
                serverMessage = e.getMessage();
            } else {
                serverMessage = e.toString();
            }
        }
        Configuration.setStateOfClient(StateOfClient.OFFLINE);
        return serverMessage;
    }

    private void sendMessage2StopDownloadThreadUnexpectlyHandle(String message) {
        if (stopDownloadThreadUnexpectly != null) {
            Bundle bundle = new Bundle();
            Message msg = new Message();

            bundle.putString(Configuration.STOP_DOWNLOAD_THREAD_MESSAGE_KEY,
                    message);
            msg.setData(bundle);
            stopDownloadThreadUnexpectly.sendMessage(msg);
        }
    }

    private void sendMessage2PictureDownloadedHandler(String title) {
        if (pictureDownloadedHandler != null) {
            //Log.i(Configuration.APP_TAG, "Download finish: " + title);
            Bundle bundle = new Bundle();
            Message msg = new Message();

            bundle.putString(Configuration.LOCAL_FILE_PATH, title);
            msg.setData(bundle);
            pictureDownloadedHandler.sendMessage(msg);
        }
    }
}
